/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *   Mupen64plus-core - m64p_plugin.h                                      *
 *   Mupen64Plus homepage: http://code.google.com/p/mupen64plus/           *
 *   Copyright (C) 2002 Hacktarux                                          *
 *   Copyright (C) 2009 Richard Goedeken                                   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#ifndef M64P_DEVICE_H
#define M64P_DEVICE_H

#include "m64p_types.h"

/*** Controller plugin's ****/
#define PLUGIN_NONE                 1
#define PLUGIN_MEMPAK               2
#define PLUGIN_RUMBLE_PAK           3 /* not implemeted for non raw data */
#define PLUGIN_TANSFER_PAK          4 /* not implemeted for non raw data */
#define PLUGIN_RAW                  5 /* the controller plugin is passed in raw data */

/***** Structures *****/
typedef struct _FramebufferInfo
{
	unsigned int addr;
	unsigned int size;
	unsigned int width;
	unsigned int height;
} FrameBufferInfo;

typedef struct _RspInterface {
    unsigned int * SP_MEM_ADDR_REG;
    unsigned int * SP_DRAM_ADDR_REG;
    unsigned int * SP_RD_LEN_REG;
    unsigned int * SP_WR_LEN_REG;
    unsigned int * SP_STATUS_REG;
    unsigned int * SP_DMA_FULL_REG;
    unsigned int * SP_DMA_BUSY_REG;
    unsigned int * SP_PC_REG;
    unsigned int * SP_SEMAPHORE_REG;

    unsigned int * DPC_START_REG;
    unsigned int * DPC_END_REG;
    unsigned int * DPC_CURRENT_REG;
    unsigned int * DPC_STATUS_REG;
    unsigned int * DPC_CLOCK_REG;
    unsigned int * DPC_BUFBUSY_REG;
    unsigned int * DPC_PIPEBUSY_REG;
    unsigned int * DPC_TMEM_REG;

    void (*ProcessDlist)(void);
    void (*ProcessAlist)(void);
    void (*ProcessRdpList)(void);
} RspInterface;

typedef struct _RdpInterface {
    unsigned int * DPC_START_REG;
    unsigned int * DPC_END_REG;
    unsigned int * DPC_CURRENT_REG;
    unsigned int * DPC_STATUS_REG;
    unsigned int * DPC_CLOCK_REG;
    unsigned int * DPC_BUFBUSY_REG;
    unsigned int * DPC_PIPEBUSY_REG;
    unsigned int * DPC_TMEM_REG;

    unsigned int * VI_STATUS_REG;
    unsigned int * VI_ORIGIN_REG;
    unsigned int * VI_WIDTH_REG;
    unsigned int * VI_INTR_REG;
    unsigned int * VI_V_CURRENT_LINE_REG;
    unsigned int * VI_TIMING_REG;
    unsigned int * VI_V_SYNC_REG;
    unsigned int * VI_H_SYNC_REG;
    unsigned int * VI_LEAP_REG;
    unsigned int * VI_H_START_REG;
    unsigned int * VI_V_START_REG;
    unsigned int * VI_V_BURST_REG;
    unsigned int * VI_X_SCALE_REG;
    unsigned int * VI_Y_SCALE_REG;

	void (*ChangeWindow)(void);
	void (*MoveScreen)(int x, int y);
	void (*ShowCFB)(void);
	void (*UpdateScreen)(void);
	void (*ViStatusChanged)(void);
	void (*ViWidthChanged)(void);
	void (*ReadScreen2)(void *dest, int *width, int *height, int front);
	void (*SetRenderingCallback)(void (*callback)(int));
	void (*FBRead)(unsigned int addr);
	void (*FBWrite)(unsigned int addr, unsigned int size);
	void (*FBGetFrameBufferInfo)(void *p);

} RdpInterface;

typedef struct _AudioInterface {
    unsigned int * AI_DRAM_ADDR_REG;
    unsigned int * AI_LEN_REG;
    unsigned int * AI_CONTROL_REG;
    unsigned int * AI_STATUS_REG;
    unsigned int * AI_DACRATE_REG;
    unsigned int * AI_BITRATE_REG;

	void (*AiDacrateChanged)(int SystemType);
	void (*AiLenChanged)(void);
	int  (*InitiateAudio)(void);
	void (*ProcessAList)(void);
	void (*SetSpeedFactor)(int percent);
	void (*VolumeUp)(void);
	void (*VolumeDown)(void);
	int  (*VolumeGetLevel)(void);
	void (*VolumeSetLevel)(int level);
	void (*VolumeMute)(void);
	const char * (*VolumeGetString)(void);
} AudioInterface;

typedef union _ControllerButtonInterface {
    unsigned int Value;
    struct {
        unsigned R_DPAD       : 1;
        unsigned L_DPAD       : 1;
        unsigned D_DPAD       : 1;
        unsigned U_DPAD       : 1;
        unsigned START_BUTTON : 1;
        unsigned Z_TRIG       : 1;
        unsigned B_BUTTON     : 1;
        unsigned A_BUTTON     : 1;

        unsigned R_CBUTTON    : 1;
        unsigned L_CBUTTON    : 1;
        unsigned D_CBUTTON    : 1;
        unsigned U_CBUTTON    : 1;
        unsigned R_TRIG       : 1;
        unsigned L_TRIG       : 1;
        unsigned Reserved1    : 1;
        unsigned Reserved2    : 1;

        signed   X_AXIS       : 8;
        signed   Y_AXIS       : 8;
    };
} ControllerButtonInterface;

typedef struct _ControllerInterface {
    int Present;
    int RawData;
    int Plugin;
	void (*ControllerCommand)(int Control, unsigned char *Command);
	void (*GetKeys)(int Control, ControllerButtonInterface *Keys);
	//void (*InitiateController)(void);
	void (*ReadController)(int Control, unsigned char *Command);
	void (*SDL_KeyDown)(int keymod, int keysym);
	void (*SDL_KeyUp)(int keymod, int keysym);
} ControllerInterface;

typedef struct _ControllersInterface {
    ControllerInterface **Controls;      /* A pointer to an array of 4 controllers .. eg:  CONTROL Controls[4]; */
	void (*InitiateControllers)(void);
} ControllersInterface;

typedef struct _CoreInterface
{
	unsigned char * HEADER;
	unsigned int * MI_INTR_REG;
    unsigned char * RDRAM;
    unsigned char * DMEM;
    unsigned char * IMEM;
	void (*CheckInterrupts)(void); // Check interupts
} CoreInterface;


// Global interface tables for our devices
extern RspInterface *g_RspInterface;
extern RdpInterface *g_RdpInterface;
extern ControllersInterface *g_ControllersInterface;
extern AudioInterface *g_AudioInterface;
extern CoreInterface *g_CoreInterface;

#ifdef __cplusplus
extern "C" {
#endif

void InitAudio();
void ShutdownAudio();
void InitInput();
void ShutdownInput();
void InitVideo();
void ShutdownVideo();
void InitDevices();
void ShutdownDevices();
void InitCore();
void StartVideo(void);

#ifdef __cplusplus
}
#endif

#endif /* M64P_DEVICE_H */


